//
// Created by hoyin on 2022/3/7.
//

#ifndef AUST_RM_VISION_2022_IMAGESTREAM_H
#define AUST_RM_VISION_2022_IMAGESTREAM_H

#include "opencv2/opencv.hpp"
#include "Chrono.h"
#include "MVCamera.h"
#include "thread"

using namespace cv;
using namespace mvc;
using namespace std;

class ImageStream {
private:
	Chrono chrono;
	VideoCapture* vc{};
	MVCamera* mvc{};
	Mat curFrame;
	double timeFlag = 0;

	static void updateImage(Chrono& chrono, double& timeFlag, int timeSpan, Mat& curFrame, VideoCapture* vc=nullptr, MVCamera* mvc=nullptr) {
		if (vc != nullptr) {
			while (vc->isOpened()) {
				vc->read(curFrame);
				timeFlag = chrono.timeCost();
				this_thread::sleep_for(std::chrono::milliseconds(timeSpan));
			}
		}
	}
	
public:
	void init(VideoCapture* videoCapture, int timeSpan) {
		chrono.reset();
		vc = videoCapture;
		mvc = nullptr;
		thread imageUpdateThread(updateImage, ref(chrono), ref(timeFlag), timeSpan, ref(curFrame), vc, nullptr);
		imageUpdateThread.detach();
	}

	void init(MVCamera* mvCamera, int timeSpan) {
		chrono.reset();
		mvc = mvCamera;
		vc = nullptr;
		thread imageUpdateThread(updateImage, ref(chrono), ref(timeFlag), timeSpan, ref(curFrame), nullptr, mvc);
		imageUpdateThread.detach();
	}

	ImageStream() = default;

	void read(Mat& frame, double& t) {
		frame = curFrame.clone();
		t = timeFlag;
	}

	bool isOK() {
		return vc->isOpened() || mvc->isOK();
	}
};

#endif //AUST_RM_VISION_2022_IMAGESTREAM_H
